﻿// **********************************************************************
//
// Author: KingSley
// Email:3268374537@qq.com
// Created:	2018/8/1   10:25
// Introduce: 对角色属性的控制与管理
//
// **********************************************************************
using UnityEngine;

namespace KingSley
{
    [AddComponentMenu("KingARPG/属性数据/玩家属性控制器")]
    public class PlayerAttributeControl : MonoSingleton<PlayerAttributeControl>
    {
        /// <summary>
        /// 处理前提判断
        /// </summary>
        public bool GetLvUp = true;
        public bool GrowthisAdd = false;
        public bool IsDeath = false;
        /// <summary>
        /// 最高等级
        /// </summary>
        public int MaxLV;
        /// <summary>
        /// 当前等级所需要的经验总量
        /// </summary>
        public float NeedExpPerLV;
        /// <summary>
        /// 当前等级到下一个等级还需要的经验量
        /// </summary>
        public float EXP2NextLV;
        /// <summary>
        /// 到当前为止所获得的所有经验量
        /// </summary>
        public float MaxExp;

        /// <summary>
        /// 各类的实例对象
        /// </summary>
        public BaseAttribute BaseStatus;
        public AdditionAttribute AddStatus;
        public CurAttribute CurStatus;
        public AttributeGrowth attributeGrowth, growthPoint;
        public SumAttribute SumStatus;

        /// <summary>
        /// 各类动作的速度
        /// </summary>
        public float RunSpeed;
        public float WalkSpeed;
        public float TurnSpeed;
        public float BackSpeed;

        public void CalculateExp()
        {
            // 更新到当前等级为止的所有经验，包括本级到下一级
            MaxExp = 40.0f * BaseStatus.LV * BaseStatus.LV + 60.0f * BaseStatus.LV;
            // 更新本级到下一级所需要的经验值；
            NeedExpPerLV = MaxExp - (40.0f * (BaseStatus.LV - 1) * (BaseStatus.LV - 1) + 60.0f * (BaseStatus.LV - 1));
        }

        /// <summary>
        /// 更新经验值
        /// </summary>
        public void UpdateExp()
        {
            if (BaseStatus.LV >= MaxLV)
            {
                BaseStatus.Exp = NeedExpPerLV;
                BaseStatus.LV = MaxLV;
            }
            else
            {
                if (BaseStatus.Exp >= NeedExpPerLV)
                {
                    GetLvUp = true;
                    // 更新当前在本级拥有经验
                    BaseStatus.Exp = BaseStatus.Exp - NeedExpPerLV;
                    // 更新等级
                    BaseStatus.LV += 1;

                    CalculateExp();
                    GrowthisAdd = false;
                    // 更新属性
                    UpdateAttribute();

                    CurStatus.CurHP = SumStatus.HP;
                    CurStatus.CurMP = SumStatus.MP;
                }
            }
        }

        /// <summary>
        /// 更新属性值
        /// </summary>
        public void UpdateAttribute()
        {
            if (!GrowthisAdd)
            {
                CalculateAttributePointGrowth();
                BaseStatus.HP += attributeGrowth.HP;
                BaseStatus.MP += attributeGrowth.MP;
                BaseStatus.Attack += attributeGrowth.Attack;
                BaseStatus.Defend += attributeGrowth.Defend;
                BaseStatus.Strong += attributeGrowth.Strong;
                BaseStatus.Intelligence += attributeGrowth.Intelligence;
                BaseStatus.Agility += attributeGrowth.Agility;
                BaseStatus.Power += attributeGrowth.Power;
                GrowthisAdd = true;
            }
            SumStatus.Strong = BaseStatus.Strong + AddStatus.Strong;
            SumStatus.Intelligence = BaseStatus.Intelligence + AddStatus.Intelligence;
            SumStatus.Agility = BaseStatus.Agility + AddStatus.Agility;
            SumStatus.Power = BaseStatus.Power + AddStatus.Power;

            SumStatus.Attack = BaseStatus.Attack + AddStatus.Attack + Mathf.FloorToInt(SumStatus.Strong * 0.2f);
            SumStatus.Defend = BaseStatus.Defend + AddStatus.Defend + Mathf.FloorToInt(SumStatus.Power * 0.2f);

            SumStatus.HP = BaseStatus.HP + AddStatus.HP + Mathf.FloorToInt(SumStatus.Strong * 0.4f);
            SumStatus.MP = BaseStatus.MP + AddStatus.MP + Mathf.FloorToInt(SumStatus.Intelligence * 0.4f);
            SumStatus.AttackSpeed = BaseStatus.AttackSpeed + AddStatus.AttackSpeed + Mathf.FloorToInt(SumStatus.Agility * 0.2f);
            SumStatus.MoveSpeed = BaseStatus.MoveSpeed + AddStatus.MoveSpeed + Mathf.FloorToInt(SumStatus.Agility * 0.3f);
            SumStatus.RotationSpeed = BaseStatus.RotationSpeed + AddStatus.RotationSpeed + Mathf.FloorToInt(SumStatus.Agility * 0.2f);
            SumStatus.CriticalRate = BaseStatus.CriticalRate + AddStatus.CriticalRate;
            SumStatus.CriticalDamage = BaseStatus.CriticalDamage + AddStatus.CriticalDamage;

            CurStatus.CurAttack = SumStatus.Attack;
            CurStatus.CurDefend = SumStatus.Defend;
            CurStatus.CurStrong = SumStatus.Strong;
            CurStatus.CurIntelligence = SumStatus.Intelligence;
            CurStatus.CurAgility = SumStatus.Agility;
            CurStatus.CurPower = SumStatus.Power;
            CurStatus.CurCriticalRate = SumStatus.CriticalRate;
            CurStatus.CurCriticalDamage = SumStatus.CriticalDamage;
        }

        /// <summary>
        /// 计算属性值增长
        /// </summary>
        void CalculateAttributePointGrowth()
        {
            if (growthPoint.HP > 0)
            {
                attributeGrowth.HP += 2 * growthPoint.HP;

            }
            if (growthPoint.Attack > 0)
            {
                attributeGrowth.Attack += 2 * growthPoint.Attack;
            }
            if (growthPoint.MP > 0)
            {
                attributeGrowth.MP += 2 * growthPoint.MP;
            }
            if (growthPoint.Defend > 0)
            {
                attributeGrowth.Defend += 2 * growthPoint.Defend;
            }
            if (growthPoint.Strong > 0)
            {
                attributeGrowth.Strong += 2 * growthPoint.Strong;
            }
            if (growthPoint.Intelligence > 0)
            {
                attributeGrowth.Intelligence += 2 * growthPoint.Intelligence;
            }
            if (growthPoint.Agility > 0)
            {
                attributeGrowth.Agility += 2 * growthPoint.Agility;
            }
            if (growthPoint.Power > 0)
            {
                attributeGrowth.Power += 2 * growthPoint.Power;
            }
        }

        /// <summary>
        /// 检测HP、MP的当前值是否超出规定，每帧调用
        /// </summary>
        void CheckHPMP()
        {
            if (!IsDeath) 
            {
                CurStatus.CurHP += Mathf.FloorToInt(BaseStatus.HPRecoverPerSecond * 0.33f);
                CurStatus.CurMP += Mathf.FloorToInt(BaseStatus.MPRecoverPerSecond * 0.50f);
            }
            else
            {
                CurStatus.CurHP = 0;
                CurStatus.CurMP = 0;
            }
            if (CurStatus.CurHP < 0)
                CurStatus.CurHP = 0;
            if (CurStatus.CurMP < 0)
                CurStatus.CurMP = 0;
            if (CurStatus.CurHP >= SumStatus.HP)
                CurStatus.CurHP = SumStatus.HP;
            if (CurStatus.CurMP >= SumStatus.MP)
                CurStatus.CurMP = SumStatus.MP;
        }
    }
}